package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.CodeEnum;
import com.ruoyi.common.exception.JGException;
import com.ruoyi.common.utils.Result;
import com.ruoyi.common.utils.ResultUtil;
import com.ruoyi.system.domain.SelectTrainingPolling;
import com.ruoyi.system.domain.SysTraining;
import com.ruoyi.system.domain.SysTrainingCategory;
import com.ruoyi.system.domain.param.SysTrainingCategoryParam;
import com.ruoyi.system.domain.param.SysTrainingVideosParam;
import com.ruoyi.system.domain.vo.SysTrainingCategoryVo;
import com.ruoyi.system.domain.vo.SysTrainingVideosVo;
import com.ruoyi.system.mapper.SysTrainingCategoryMapper;
import com.ruoyi.system.mapper.SysTrainingMapper;

import com.ruoyi.system.service.ISysTrainingCategoryService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wangpengjie
 */
@Service
@AllArgsConstructor
public class SysTraningCategoryServiceImpl extends ServiceImpl<SysTrainingCategoryMapper, SysTrainingCategory> implements ISysTrainingCategoryService {

    private final SysTrainingMapper sysTrainingMapper;

    @Override
    public Result<List<SysTrainingCategoryVo>> selectTrainingCategoryPage(SysTrainingCategoryParam param) {
        List<SysTrainingCategoryVo>  categoryVoIPage= baseMapper.selectSysTrainingCategoryPage(param);
        //查询所有分类信息
        List<SysTrainingCategoryVo> list = baseMapper.selectListTwo(param.getProjectId());
        Map<Integer, List<SysTrainingCategoryVo>> map = list.stream().collect(Collectors.groupingBy(SysTrainingCategoryVo::getParentId));
        List<SysTrainingCategoryVo> treeSelectList = treeSelectListTwo(categoryVoIPage, map);
        return ResultUtil.data(treeSelectList);
    }

    @Override
    public Result submit(SysTrainingCategory trainingCategory) {

        QueryWrapper queryWrapper =new QueryWrapper();
        queryWrapper.eq("name", trainingCategory.getName());
        queryWrapper.eq("project_id", trainingCategory.getProjectId());
        queryWrapper.eq("is_deleted",0);
        if(null != trainingCategory.getParentId() && trainingCategory.getParentId() > 0){
            queryWrapper.eq("parent_id",trainingCategory.getParentId());
        }else{
            queryWrapper.eq("parent_id",0);
        }
        Long count = baseMapper.selectCount(queryWrapper);
        if (count > 0L){
            throw new JGException(CodeEnum.CATEGORY_CLASSIFY_NAME);
        }
        boolean save = this.save(trainingCategory);
        if (save){
            return ResultUtil.status(CodeEnum.SUCCESS.getSuccess());
        }else{
            return ResultUtil.error(CodeEnum.CATEGORY_CLASSIFY_ADD.getCode(),CodeEnum.CATEGORY_CLASSIFY_ADD.getMessage());
        }
    }

    @Override
    public Result removeById(String ids,Long projectId) {
        //判断是否有子集
       Long count = this.baseMapper.isDeleteTraining(Long.valueOf(ids),projectId);
       if(count > 0L){
           throw new JGException(CodeEnum.CATEGORY_CLASSIFY_DELETETO);
       }
        count = this.baseMapper.isDeleteTrainingParentId(Long.valueOf(ids),projectId);
        if(count > 0L){
            throw new JGException(CodeEnum.CATEGORY_CLASSIFY_DELETETO);
        }
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.set("is_deleted",1);
        updateWrapper.eq("id",ids);
        return ResultUtil.status(this.update(updateWrapper));
    }

    @Override
    public Result updateSysTrainingCategory(SysTrainingCategory trainingCategory) {
        QueryWrapper queryWrapper =new QueryWrapper();
        queryWrapper.eq("name", trainingCategory.getName());
        queryWrapper.eq("project_id", trainingCategory.getProjectId());
        queryWrapper.eq("is_deleted",0);
        if(null != trainingCategory.getParentId() && trainingCategory.getParentId() > 0){
            queryWrapper.eq("parent_id",trainingCategory.getParentId());
        }else{
            queryWrapper.eq("parent_id",0);
        }
        Long count = baseMapper.selectCount(queryWrapper);
        if (count > 0L){
            throw new JGException(CodeEnum.CATEGORY_CLASSIFY_NAME);
        }
        boolean updateById = this.updateById(trainingCategory);
        if (updateById){
            return ResultUtil.status(CodeEnum.SUCCESS.getSuccess());
        }else{
            return ResultUtil.error(CodeEnum.CATEGORY_CLASSIFY_UPDATE.getCode(),CodeEnum.CATEGORY_CLASSIFY_UPDATE.getMessage());
        }
    }

    @Override
    public Result<SysTrainingCategoryVo> selectSysTrainingCategoryInfo(Long id,Long projectId) {
        SysTrainingCategoryVo sysTrainingCategoryVo = baseMapper.selectInfo(id,projectId);
        //父级详情信息
        if (sysTrainingCategoryVo.getParentId()!=0) {
            SysTrainingCategory sysTrainingCategory = baseMapper.selectById(sysTrainingCategoryVo.getParentId());
            sysTrainingCategoryVo.setParentName(sysTrainingCategory.getName());
        }else {
            sysTrainingCategoryVo.setParentName("顶级");
        }
        return ResultUtil.data(sysTrainingCategoryVo);
    }

    @Override
    public Result updatePublishStorage(Long id,Integer state,Long projectId) {
        List<String> ids=new ArrayList<>();
        //判断父级是否未上架状态
        if (state==1){
            //详情信息
            SysTrainingCategoryVo info = baseMapper.selectInfo(id,projectId);
            if (info.parentId!=0){
                //父级详情信息
                SysTrainingCategoryVo parentInfo = baseMapper.selectInfo(info.getParentId().longValue(),projectId);
                if (parentInfo.getPublishState()==0){
                    throw new JGException(CodeEnum.COMMODITY_CLASSIFY_PARENT);
                }
            }
            ids.add(String.valueOf(id));
        }else {
            List<SysTrainingCategoryVo> list = baseMapper.selectListTwo(projectId);
            List<SysTrainingCategoryVo> subCategories = findSubCategories(id.intValue(), list);
            ids.add(String.valueOf(id));
            ids.addAll(subCategories.stream().map(SysTrainingCategoryVo::getId).map(Object::toString).collect(Collectors.toList()));
            if (ObjectUtils.isNotEmpty(ids)){
                ids.stream().forEach(item->{
                    //判断商品分类是否与商品进行关联
                    Long count = sysTrainingMapper.selectCount(new LambdaQueryWrapper<SysTraining>().eq(SysTraining::getTrainingCategoryId, item));
                    if (count > 0L){
                        throw new JGException(CodeEnum.CATEGORY_CLASSIFY_BINDING);
                    }
                });
            }
        }
        boolean update = this.update(Wrappers.<SysTrainingCategory>lambdaUpdate()
                .set(SysTrainingCategory::getPublishState, state)
                .eq(SysTrainingCategory::getProjectId, projectId)
                .in(SysTrainingCategory::getId, ids));
        if (update){
            return ResultUtil.status(CodeEnum.SUCCESS.getSuccess());
        }else{
            return ResultUtil.error(CodeEnum.CATEGORY_CLASSIFY_UPDATE.getCode(),CodeEnum.CATEGORY_CLASSIFY_UPDATE.getMessage());
        }
    }

    @Override
    public Result selectAllTrainingCategory(Long projectId) {
        //通过项目id查询顶级分类信息
        List<SysTrainingCategoryVo> list = baseMapper.selectAllList(projectId);
        List<SysTrainingCategoryVo> selectList1 = baseMapper.selectListTwo(projectId);
        Map<Integer, List<SysTrainingCategoryVo>> map = selectList1.stream().filter(item->item.getPublishState()!=0).collect(Collectors.groupingBy(SysTrainingCategoryVo::getParentId));
        return ResultUtil.data(treeSelectListTwo(list,map));
    }

    @Override
    public Result<IPage<SysTrainingVideosVo>> videos(SysTrainingVideosParam param) {
        IPage<SysTrainingVideosVo>  categoryVoIPage= baseMapper.selectVideos(new Page<>(param.getCurrent(),param.getSize()),param);
        for (SysTrainingVideosVo record : categoryVoIPage.getRecords()) {
            record.setUrls(baseMapper.selectUrls(record.getTrainingCategoryId()));
            record.setFileName(String.join(",", baseMapper.selectFileName(record.getTrainingCategoryId())));
        }

        return ResultUtil.data(categoryVoIPage);
    }

    @Override
    public Result start(Integer id) {
        int update = baseMapper.update(null, Wrappers.<SysTrainingCategory>lambdaUpdate().eq(SysTrainingCategory::getId, id).set(SysTrainingCategory::getStatus, 0));
        if (update > 0) {
            return ResultUtil.status(true);
        } else {
            return ResultUtil.status(false);
        }
    }

    @Override
    public Result stop(Integer id) {
        int update = baseMapper.update(null, Wrappers.<SysTrainingCategory>lambdaUpdate().eq(SysTrainingCategory::getId, id).set(SysTrainingCategory::getStatus, 1));
        if (update > 0) {
            return ResultUtil.status(true);
        } else {
            return ResultUtil.status(false);
        }
    }

    @Override
    public Result<List<SelectTrainingPolling>> selectPolling(Long id) {
        return ResultUtil.data(selectTrainingPolling(id));
    }
    List<SelectTrainingPolling>  selectTrainingPolling(Long id){
        List<SelectTrainingPolling> selectTrainingPollings = new ArrayList<>();
        SelectTrainingPolling selectTrainingPolling = new SelectTrainingPolling();
        SysTrainingCategory sysTrainingCategories =baseMapper.selectTrainingPolling(id);
        selectTrainingPolling.setTrainingId(id);
        selectTrainingPolling.setTrainingName(sysTrainingCategories.getName());
        selectTrainingPollings.add(selectTrainingPolling);
        SysTrainingCategory sysTrainingCategory = findNodeById(sysTrainingCategories.getId());
        if(null != sysTrainingCategory){
            SelectTrainingPolling selectTrainingPolling1 = new SelectTrainingPolling();
            selectTrainingPolling1.setTrainingId(Long.valueOf(sysTrainingCategory.getId()));
            selectTrainingPolling1.setTrainingName(sysTrainingCategory.getName());
            selectTrainingPollings.add(selectTrainingPolling1);
            while (null != sysTrainingCategory) {
                sysTrainingCategory = findNodeById(sysTrainingCategory.id);
                if (null != sysTrainingCategory) {
                    SelectTrainingPolling selectTrainingPolling2 = new SelectTrainingPolling();
                    selectTrainingPolling2.setTrainingId(Long.valueOf(sysTrainingCategory.getId()));
                    selectTrainingPolling2.setTrainingName(sysTrainingCategory.getName());
                    selectTrainingPollings.add(selectTrainingPolling2);
                }

            }
        }
        return selectTrainingPollings;
    }
    private  SysTrainingCategory findNodeById(Integer id) {
        List<SysTrainingCategory> sysTrainingCategories = baseMapper.selectTrainingPollingParent(Long.valueOf(id));
        if(sysTrainingCategories.size()>0){
            SysTrainingCategory sysTrainingCategory =  sysTrainingCategories.get(0);
            return sysTrainingCategory;
        }
        return null;
    }
    private  List<SysTrainingCategoryVo> treeSelectListTwo(List<SysTrainingCategoryVo> list, Map<Integer, List<SysTrainingCategoryVo>> map) {
        if(list == null || list.isEmpty()){
            return list;
        }
        for(SysTrainingCategoryVo vo : list){
            if(map.containsKey(vo.getId())){
                treeSelectListTwo(map.get(vo.getId()), map);
                vo.setProductCategoryList(map.get(vo.getId()));
            }
        }
        return list;
    }

    public List<SysTrainingCategoryVo> findSubCategories(int categoryId, List<SysTrainingCategoryVo> categories) {
        List<SysTrainingCategoryVo> subCategories = new ArrayList<>();
        for (SysTrainingCategoryVo category : categories) {
            if (category.getParentId() == categoryId) {
                subCategories.add(category);
                subCategories.addAll(findSubCategories(category.getId(), categories));
            }
        }
        return subCategories;
    }
}
